package fuse.LaCollaFS.Metadades;

import java.util.List;

import org.jdom.Element;

import fuse.FuseFtype;
import fuse.FuseStat;

public class Fitxer extends Estructura {

	private int Versions;

	private Fitxer VAnterior;

	private String IdObjecte;

	private MetaDades dades;

	/**
	 * Constructor de la clase Fitxer
	 * 
	 * Li passem el nom del fitxer i una referencia a les metadades. Ens
	 * crearà l'estructura Fitxer de les metadades, pero no el fitxer fisic.
	 * Ens inicialitzarà el numero de versions a 1 i el FuseStat amb l'hora
	 * actual i els parametres per defecte d'un fitxer. mode fitxer i 644
	 * usuari i grup 0
	 * 
	 * El IdObject ho deixarà en blanc el VAnterior apuntarà a si mateix.
	 * 
	 * 
	 */
	public Fitxer(String nom, MetaDades a) {


		this.defFitxer();
		this.setNom(nom);
		dades = a;
		Versions = 1;
		IdObjecte = "null";

		VAnterior = null;

		FuseStat Estat = this.getStat();
		Estat = new FuseStat();

		Estat.atime = (int) (System.currentTimeMillis() / 1000L);

		Estat.ctime = (int) (int) (System.currentTimeMillis() / 1000L);

		Estat.gid = 1000; // id del grup
	//	Estat.inode = 5; // inode??? ho podem usar per l'objecte de la colla?

		Estat.mode = FuseFtype.TYPE_FILE | 0644;

		Estat.mtime = (int) (System.currentTimeMillis() / 1000L);
		Estat.nlink = 1; // numero d'enllassos
		Estat.size = 0; // tamany
		Estat.uid = 1000; // id usuari
		Estat.blocks = (int) ((Estat.size + 511L) / 512L);
		this.setStat(Estat);
	}

	/**
	 * Elimina de les metadades un el fitxer que el crida Si té versions,
	 * asigna la VAnterior com a fill del directori Pare. Si no té versions,
	 * crida al metode delete
	 */

	public void Eliminar() {

		
		//pare.EliminarFill(this.getNom());
		if (Versions > 1) {
			Directori pare = (Directori) dades.ObtenirNode(this.getPare().ObtenirPath());
			pare.AfegirFill(VAnterior);
		}
		this.delete();

	}

	/**
	 * 
	 */
	public void Purge_() {


		if (Versions > 1) {
			VAnterior.Purge_();

		}

		VAnterior.delete();

	}

	/**
	 * Elimina el fitxer i totes les versions. No elimina les dades de
	 * lacolla, només elimina l'enllaç a les metadades Quan lacolla
	 * implementi el metode rmobject, s'haurà de retocar perque elimini tb
	 * les dades
	 */
	public void Purge() {

		Directori p;
		Purge_();
		p = (Directori) dades.ObtenirNode(this.getPare().ObtenirPath());
		p.EliminarFill(this.getNom());

	}

	/**
	 * Retorna el objecte de la versió anterior.
	 */
	public Estructura Anterior() {

		return VAnterior;
	}

	/**
	 * Retorna el numero de versions del fitxer
	 */
	public int getVersion() {


		return Versions;
	}

	/**
	 * Agrega a l'estructura el id de lacolla per a les dades físiques del
	 * fitxer
	 */
	public void setIdObjecte(String path) {

		IdObjecte = path;

	}

	/**
	 * Recupera les dades del fitxer
	 */
	public String getIdObjecte() {

		return IdObjecte;
	}

	/**
	 * Retorna una copia del fitxer.
	 */
	public Fitxer copy() {

		Fitxer fit = new Fitxer(this.getNom(), dades);
		
		FuseStat estat = this.getStat();
		estat.nlink = estat.nlink +1;
		fit.setStat(estat);
		this.setStat(estat);
		fit.setIdObjecte(this.getIdObjecte());
		
		fit.setPare(this.getPare());
		fit.setVAnterior(this.getVanterior());
		fit.setVersions(fit.getVersion());
		
		

		return fit;
	}
	
	/**
	 * Retorna el valor de la versió anterior
	 * @return
	 */
	public Fitxer getVanterior() {
		
		// TODO Auto-generated method stub
		return VAnterior;
	}

	/**
	 * Crea l'Element XML del objecte i tot el que conté.
	 */
	public Element CrearXML() {

		Element fill = new Element("Fitxer");
		p(this.IdObjecte);
		fill.setAttribute("Nom", this.getNom());
		fill.setAttribute("IdObjecte", this.IdObjecte);
		//fill.setAttribute("VAnterior", this.VAnterior.getIdObjecte());
		fill.setAttribute("Versions", String.valueOf(this.Versions));
		
		Element estat = new Element("Stat");

		estat.setAttribute("atime", String.valueOf(this.getStat().atime));
		estat.setAttribute("blocks", String.valueOf(this.getStat().blocks));
		estat.setAttribute("ctime", String.valueOf(this.getStat().ctime));
		estat.setAttribute("gid", String.valueOf(this.getStat().gid));
//		estat.setAttribute("inode", String.valueOf(this.getStat().inode));
		estat.setAttribute("mode", String.valueOf(this.getStat().mode));
		estat.setAttribute("mtime", String.valueOf(this.getStat().mtime));
		estat.setAttribute("nlink", String.valueOf(this.getStat().nlink));
		estat.setAttribute("size", String.valueOf(this.getStat().size));
		estat.setAttribute("uid", String.valueOf(this.getStat().uid));
		fill.addContent(estat);

		
		if (VAnterior != null){
		Element Versioanterior;
		Versioanterior = VAnterior.CrearXML();
		fill.addContent(Versioanterior);
		}		
		
		if (this.getPare() == null) {
			p("node arrel, no te pare");
			fill.setAttribute("Pare", "/media/");
		} else
			fill.setAttribute("Pare", this.getPare().getNom());

		return fill;
	}

	private void p(Object o) {
		/**
		 * Imprimeix per pantalla
		 */
		System.out.println(o);

	}
	/**
	 * Recupera la info guarda en Element XML sobre l'objecte i actualitza
	 * els parametres del Objecte Fitxer
	 */
	public void LlegirXML(Element root) {

		Element stat;
		this.setNom(root.getAttributeValue("Nom"));

	//	this.setPare(root.getAttributeValue("Pare"));
		this.setIdObjecte(root.getAttributeValue("IdObjecte"));

		this.setVersions(Integer.valueOf(root.getAttributeValue("Versions"))
				.intValue());

	//	this.setVAnterior(root.getAttributeValue("VAnterior"));
		// p("el nom del fitxer es "+ this.getNom());
		List l = root.getChildren();
		stat = (Element) l.get(0);
		// p("Stat Type: " + stat.getName());

		FuseStat estat;
		estat = this.getStat();
		// omplir stat.....
		estat.atime = Integer.valueOf(stat.getAttributeValue("atime"))
				.intValue();
		estat.blocks = Integer.valueOf(stat.getAttributeValue("blocks"))
				.intValue();
		estat.ctime = Integer.valueOf(stat.getAttributeValue("ctime"))
				.intValue();
		estat.gid = Integer.valueOf(stat.getAttributeValue("gid")).intValue();
	//	estat.inode = Integer.valueOf(stat.getAttributeValue("inode"))
	//			.intValue();
		estat.mode = Integer.valueOf(stat.getAttributeValue("mode")).intValue();
		estat.mtime = Integer.valueOf(stat.getAttributeValue("mtime"))
				.intValue();
		estat.nlink = Integer.valueOf(stat.getAttributeValue("nlink"))
				.intValue();
		estat.size = Integer.valueOf(stat.getAttributeValue("size")).intValue();
		estat.uid = Integer.valueOf(stat.getAttributeValue("uid")).intValue();
		this.setStat(estat);
		// p(" em dic " + this.getNom());
		if(l.size() == 2){
			Element node = (Element) l.get(1);
			VAnterior = new Fitxer(node.getAttributeValue("Nom"), dades);
			VAnterior.LlegirXML(node);
			
			
		}

	}

	/**
	 * Modifica el Anterior ( TODO )
	 * 
	 */
	public void setVAnterior(Fitxer va) {
	
		// TODO Auto-generated method stub
		// VAnterior.setNom(va);

	}

	/**
	 * Modifica el numero de versions
	 * @param i Nou valor per a les versions
	 */
	public void setVersions(int v) {

		Versions = v;

	}

}